package com.travel.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.travel.common.UserContext;
import com.travel.entity.dto.AiRequestParam;
import com.travel.entity.dto.TravelPlanDTO;
import com.travel.entity.po.TravelPlan;
import com.travel.entity.po.User;
import com.travel.entity.vo.TravelPlanVo;
import com.travel.exception.BusinessException;
import com.travel.mapper.TravelPlanMapper;
import com.travel.mapper.UserMapper;
import com.travel.service.TravelPlanService;
import com.travel.utils.JWTUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author:Jasenon_ce
 * @Date: 2025/03/16/下午5:26
 */
@Service
@Slf4j
public class TravelPlanServiceImpl implements TravelPlanService {

    private static final String BEARER_PREFIX = "Bearer ";
    
    @Autowired
    private TravelPlanMapper travelPlanMapper;
    
    @Autowired
    private UserMapper userMapper;

    @Override
    public void createTravelPlan(TravelPlanDTO travelPlanDTO, HttpServletRequest request) {
        // 从请求头获取token并处理Bearer前缀
        String authHeader = request.getHeader("Authorization");
        String token = null;
        
        if (StringUtils.hasText(authHeader) && authHeader.startsWith(BEARER_PREFIX)) {
            token = authHeader.substring(BEARER_PREFIX.length());
            log.debug("提取到token: {}", token.substring(0, Math.min(token.length(), 20)) + "...");
        } else {
            log.warn("Authorization头格式不正确或为空");
            // 可以考虑直接从UserContext获取用户信息
            if (UserContext.getUserId() != null) {
                User user = new User();
                user.setId(UserContext.getUserId());
                user.setPreferredLanguage(UserContext.getPreferredLanguage());
                // 从数据库获取完整用户信息...
                // 处理逻辑...
                return;
            }
            throw new RuntimeException("无法获取有效的用户令牌");
        }
        
        AsyncCreateTravelPlan plan = new AsyncCreateTravelPlan(travelPlanDTO, token);
        plan.start();
    }
    
    @Override
    public List<TravelPlanVo> getUserTravelPlans() {
        // 从UserContext获取当前用户ID
        Long userId = UserContext.getUserId();
        if (userId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 从数据库获取用户名
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 构建查询条件
        LambdaQueryWrapper<TravelPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TravelPlan::getUsername, user.getUsername())
               .orderByDesc(TravelPlan::getCreateTime)
               .select(TravelPlan::getId, TravelPlan::getUsername, 
                      TravelPlan::getTitle, TravelPlan::getCreateTime, 
                      TravelPlan::getStartTime, TravelPlan::getEndTime);
        
        // 查询数据库
        List<TravelPlan> travelPlans = travelPlanMapper.selectList(wrapper);
        
        // 转换为VO对象
        List<TravelPlanVo> voList = travelPlans.stream()
                .map(plan -> {
                    TravelPlanVo vo = new TravelPlanVo();
                    BeanUtils.copyProperties(plan, vo);
                    return vo;
                })
                .collect(Collectors.toList());
        
        log.info("查询用户[{}]的所有旅行计划，共{}条", user.getUsername(), voList.size());
        return voList;
    }
    
    @Override
    public TravelPlan getTravelPlanById(Long planId) {
        // 从UserContext获取当前用户ID
        Long userId = UserContext.getUserId();
        if (userId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 查询指定ID的旅行计划
        TravelPlan travelPlan = travelPlanMapper.selectById(planId);
        if (travelPlan == null) {
            throw new BusinessException("旅行计划不存在");
        }
        
        // 从数据库获取用户名并验证权限
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证该计划是否属于当前用户
        if (!travelPlan.getUsername().equals(user.getUsername())) {
            throw new BusinessException("无权查看此旅行计划");
        }
        
        log.info("查询旅行计划详情, id: {}, title: {}", planId, travelPlan.getTitle());
        return travelPlan;
    }

    class AsyncCreateTravelPlan extends Thread {

        private final TravelPlanDTO travelPlanDTO;
        private final String token;

        private final String api_key = "app-GMlvPiHqnnKxSx3EUVGYX2oO";
        private final String api_url = "https://api.dify.ai/v1/workflows/run";
        private final BasicHeader basicHeader = new BasicHeader("Authorization", "Bearer " + api_key);

        public AsyncCreateTravelPlan(TravelPlanDTO travelPlanDTO, String token) {
            this.travelPlanDTO = travelPlanDTO;
            this.token = token;
        }

        public void run() {
            log.info("开始创建旅行计划: {}", travelPlanDTO);
            try {
                // 从token获取用户信息
                User user = JWTUtil.getUser(token);
                
                if (user == null) {
                    log.error("无法从token中获取用户信息");
                    return;
                }

                Map param = Map.of("text", travelPlanDTO.getText());
                AiRequestParam requestBody = AiRequestParam.builder().inputs(param)
                        .user(user.getUsername())
                        .build();

                try (CloseableHttpClient httpClient = HttpClients.custom().build()) {
                    String json_ = JSONObject.toJSONString(requestBody);
                    StringEntity s = new StringEntity(json_, ContentType.APPLICATION_JSON);

                    HttpPost httpPost = new HttpPost(api_url);
                    httpPost.setHeader(basicHeader);
                    httpPost.setEntity(s);
                    httpPost.setHeader("Content-type", "application/json");


                    CloseableHttpResponse response = httpClient.execute(httpPost);
                    String responseStr = EntityUtils.toString(response.getEntity());
                    log.info("API原始响应: {}", responseStr);
                    
                    // 解析响应JSON
                    JSONObject jsonResponse = JSONObject.parseObject(responseStr);
                    
                    // 保存到数据库的内容
                    String planContent = responseStr; // 默认存储完整响应
                    
                    // 从新的响应格式中提取result字段
                    if (jsonResponse.containsKey("data")) {
                        JSONObject data = jsonResponse.getJSONObject("data");
                        if (data != null && data.containsKey("outputs")) {
                            JSONObject outputs = data.getJSONObject("outputs");
                            if (outputs != null) {
                                String resultContent = null;
                                
                                // 尝试获取result字段
                                if (outputs.containsKey("result")) {
                                    resultContent = outputs.getString("result");
                                    log.info("成功提取outputs.result内容");
                                } 
                                // 如果不存在result字段，尝试获取text字段（向后兼容）
                                else if (outputs.containsKey("text")) {
                                    resultContent = outputs.getString("text");
                                    log.info("成功提取outputs.text内容");
                                }
                                
                                if (StringUtils.hasText(resultContent)) {
                                    planContent = resultContent; // 存储提取的内容
                                    log.info("提取到计划内容，长度为: {}", resultContent.length());
                                } else {
                                    log.warn("API返回的outputs中没有有效内容，将使用完整响应");
                                }
                            }
                        }
                    }
                    
                    // 检查API调用是否成功
                    if (jsonResponse.containsKey("data")) {
                        JSONObject data = jsonResponse.getJSONObject("data");
                        if (data != null && data.containsKey("status")) {
                            String status = data.getString("status");
                            if (!"succeeded".equals(status)) {
                                log.error("API调用未成功完成，状态: {}, 错误: {}", 
                                        status, 
                                        data.getString("error"));
                            }
                        }
                    }

                    TravelPlan travelPlan = TravelPlan.builder()
                            .username(user.getUsername())
                            .title(travelPlanDTO.getTitle())
                            .plan(planContent)
                            .createTime(new Date())
                            .startTime(travelPlanDTO.getStartTime())
                            .endTime(travelPlanDTO.getEndTime())
                            .build();

                    travelPlanMapper.insert(travelPlan);
                    log.info("成功创建旅行计划: {}, 开始时间: {}, 结束时间: {}", 
                             travelPlanDTO.getTitle(), 
                             travelPlanDTO.getStartTime(),
                             travelPlanDTO.getEndTime());

                } catch (IOException | ParseException e) {
                    log.error("调用AI API失败", e);
                    throw new RuntimeException(e);
                }
            } catch (Exception e) {
                log.error("创建旅行计划失败", e);
                throw e; // 重新抛出异常以便上层捕获
            }
        }
    }
}
